[. . . ] API Guide API Guide API Guide API Guide API Guide StorNext® SNAPI 2. 0. 1 StorNext 6-01375-05 StorNext API Guide, 6-01375-05, Ver. Quantum Corporation provides this publication "as is" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability or fitness for a particular purpose. Quantum Corporation may revise this publication from time to time without notice. StorNext copyright (c) 1991-2008 Advanced Digital Information Corporation (ADIC), Redmond, WA, USA. [. . . ] ls /tmp/; ls /var/ tmp/; cd /tmp/). Input commandString: The command you want to execute from the command line (e. g. , ls -laF /tmp /) 2 StorNext API Guide 68 Chapter 2 StorNext Storage Manager APIs API Descriptions and Arguments Output status: SUCCESS, FAILURE, SUBFAILURE, or SYNTAXERROR status code. Any response for the executed command. 2 XML Example Request: <?xml version="1. 0" encoding="UTF-8" standalone="yes" ?> <!-- Executes a specific shell command. --> <COMMAND name="PassThru"> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- commandString : valid shell command --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- The commandString argument is required exactly once. --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <ARGUMENT name="commandString" value="ls -laF /tmp"/> </COMMAND> Response: <?xml version="1. 0" encoding="UTF-8" standalone="yes" ?> <RESPONSE name="PassThru" statusCode="0" status="SUCCESS" statusDescription="Command Successful"> <STRINGINFO statusCode="0" status="SUCCESS" statusDescription="Command Successful"> <!-- An INFO tag will surround each output line. --> <INFO value="Response text goes here. "/> <INFO value="Response text goes here. "/> <INFO value="Response text goes here. "/> <INFO value="Response text goes here. "/> </STRINGINFO> </RESPONSE> 2 2 2 C++ Class Declaration class PassThru : public Request { 2 StorNext API Guide 69 Chapter 2 StorNext Storage Manager APIs API Descriptions and Arguments public: /// Primary Constructor /// This constructor is intended for primary instantiation of the object, /// given a command string. PassThru(const std::string& inCommand); /// Method to return the passthru command string const std::string& getCommandString() const; /// Method to return the results of the passthru command const std::string& getCommandResults() const; /// Method to return the local status pair const StatusPair& getLocalStatus() const; } RmDiskCopy 2 This API removes the disk copy of the specified file through explicit truncation. Input 2 filename: The pathname of the file whose on-disk copy will be removed. Output status: SUCCESS, FAILURE, SUBFAILURE, or SYNTAXERROR status code. 2 XML Example Request: <?xml version="1. 0" encoding="UTF-8" standalone="yes" ?> <!-- Truncate file data from disk. --> <COMMAND name="RmDiskCopy"> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- fileName : name of file --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- The fileName argument is required exactly once. --> 2 2 StorNext API Guide 70 Chapter 2 StorNext Storage Manager APIs API Descriptions and Arguments <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <ARGUMENT name="fileName" value="/snfs/myDirectory/myFile. dat"/> </COMMAND> Response: 2 <?xml version="1. 0" encoding="UTF-8" standalone="yes" ?> <RESPONSE name="RmDiskCopy" statusCode="0" status="SUCCESS" statusDescription="Command Successful"> <STATUSDETAIL name="filename" value="/snfs/myDirectory/myFile. dat" statusCode="0" status="SUCCESS" statusDescription="Command Successful"/> </RESPONSE> C++ Class Declaration class RmDiskCopy : public Request { public: /// Primary Constructor /// This constructor is intended for primary instantiation of the object, /// given a single filename. RmDiskCopy(const std::string& filename); /// Method to return the local status pair const StatusPair& getLocalStatus() const; } 2 SetArchiveState 2 This API allows you to set the archive state to ON or OFF. Input archiveName: The name of the archive for which you want to set the state. state: ON or OFF. 2 Output status: SUCCESS, FAILURE, SUBFAILURE, or SYNTAXERROR status code. StorNext API Guide 2 71 Chapter 2 StorNext Storage Manager APIs API Descriptions and Arguments XML Example Request: <?xml version="1. 0" encoding="UTF-8" standalone="yes" ?> <!-- Set the operating state of a specific archive. --> <COMMAND name="SetArchiveState"> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- archiveName : archive name --> <!-- state : ON, OFF --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- Each argument above is required exactly once. --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <ARGUMENT name="archiveName" value="Andromeda"/> <ARGUMENT name="state" value="ON"/> </COMMAND> Response: <?xml version="1. 0" encoding="UTF-8" standalone="yes" ?> <RESPONSE name="SetArchiveState" statusCode="0" status="SUCCESS" statusDescription="Command Successful"> <STATUSDETAIL name="archiveName" value="Andromeda" statusCode="0" status="SUCCESS" statusDescription="Command Successful"/> </RESPONSE> 2 2 2 C++ Class Declaration class SetArchiveState : public Request { public: /// State values enum StateType { ONLINE=0, OFFLINE }; /// Primary Constructor /// This constructor is intended for primary instantiation of the /// object, providing it the archive name and state. SetArchiveState(const std::string& inArchiveName, 2 StorNext API Guide 72 Chapter 2 StorNext Storage Manager APIs API Descriptions and Arguments const StateType& inArchiveState); /// Method to return the archive name const std::string& getArchiveName() const; /// Method to return the archive state const StateType& getArchiveState() const; /// Method to return the archive state as a string const std::string& getArchiveStateAsString() const; /// method to return the local status const Status& getLocalStatus() const; } SetDirAttributes 2 This API allows you to set the following directory attributes: · store (enable or disable) · truncate (enable or disable) · policy class name for the directory Input directoryName: The name of the directory for which you want to set attributes. policyClass: The name of the policy class you want to apply to the directory. 2 Output status: SUCCESS, FAILURE, SUBFAILURE, or SYNTAXERROR status code. 2 StorNext API Guide 73 Chapter 2 StorNext Storage Manager APIs API Descriptions and Arguments XML Example Request: <?xml version="1. 0" encoding="UTF-8" standalone="yes" ?> <!-- Set the attributes for a specific directory. --> <COMMAND name="SetDirAttributes"> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- directoryName : name of directory --> <!-- noTruncate : TRUE, FALSE --> <!-- noStore : TRUE, FALSE --> <!-- policyClass : valid policy class name --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- The directoryName argument is required exactly once. --> <!-- At least one of the following arguments are required, but --> <!-- no more than one of each: --> <!-- noTruncate --> <!-- noStore --> <!-- policyClass --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <ARGUMENT name="directoryName" value="/snfs/mydirectory"/> <ARGUMENT name="noTruncate" value="TRUE"/> <ARGUMENT name="noStore" value="TRUE"/> <ARGUMENT name="policyClass" value="mypolicyclass"/> </COMMAND> Response: <?xml version="1. 0" encoding="UTF-8" standalone="yes" ?> <RESPONSE name="SetDirAttributes" statusCode="0" status="SUCCESS" statusDescription="Command Successful"> <STATUSDETAIL name="directoryName" value="/snfs/mydirectory" statusCode="0" status="SUCCESS" statusDescription="Command Successful"/> </RESPONSE> 2 2 2 C++ Class Declaration class SetDirAttributes : public Request { public: /// Primary Constructor 2 StorNext API Guide 74 Chapter 2 StorNext Storage Manager APIs API Descriptions and Arguments /// This constructor is intended for primary instantiation of the object, /// providing it the directory name, policy class, truncate, and store /// settings. /// the state SetDirAttributes(const std::string& inDirectoryName, const std::string& inPolicyClass, const bool& inNoTruncate, const bool& inNoStore); /// Secondary Constructor /// This constructor is a secondary means to instantiate the object, /// the state SetDirAttributes(const std::string& inDirectoryName); /// Method to return the directory name const std::string& getDirectoryName() const; /// Method to return the policy class const std::string& getPolicyClass() const; /// Method to return the noTruncate flag bool getNoTruncateFlag() const; /// Method to return the noStore flag bool getNoStoreFlag() const; /// Method to return the local status const StatusPair& getLocalStatus() const; } SetDriveState 2 This API allows you to set the drive state to ON or OFF. Input drivename: The name of the drive whose state you want to set. state: ON or OFF. 2 StorNext API Guide 75 Chapter 2 StorNext Storage Manager APIs API Descriptions and Arguments Output status: SUCCESS, FAILURE, SUBFAILURE, or SYNTAXERROR status code. 2 XML Example Request: <?xml version="1. 0" encoding="UTF-8" standalone="yes" ?> <!-- Set the operating state of a specific drive. --> <COMMAND name="SetDriveState"> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- drivename : valid drive name --> <!-- state : ON, OFF --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <!-- Exactly one each of the above arguments is required. --> <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> <ARGUMENT name="drivename" value="lto2-001"/> <ARGUMENT name="state" value="ON"/> </COMMAND> Response: 2 2 2 <?xml version="1. 0" encoding="UTF-8" standalone="yes" ?> <RESPONSE name="SetDriveState" statusCode="0" status="SUCCESS" statusDescription="Command Successful"> <STATUSDETAIL name="drivename" value="Andromeda_LTO_Drive1" statusCode="0" status="SUCCESS" statusDescription="Command Successful"/> </RESPONSE> C++ Class Declaration class SetDriveState : public Request { public: /// Drive state values. enum DriveState { ON = 0, OFF 2 StorNext API Guide 76 Chapter 2 StorNext Storage Manager APIs API Descriptions and Arguments }; /// Primary Constructor /// This constructor is intended for primary instantiation /// of the object, providing it the drive name and state. SetDriveState(const std::string& inDriveName, const DriveState& inDriveState); /// Method to return the drivename std::string getDrivename() const; /// Method to return the drive state DriveState getDriveState() const; /// Method to return the drive state as a string std::string getDriveStateAsString() const; /// Method to return the local status pair const StatusPair& getLocalStatus() const; } SetFileAttributes 2 This API allows you to set the following attributes for a file: · store (enable or disable) · truncate (enable or disable) Input fileName: The name of the file for which you want to set attributes. [. . . ] * * This requires a 'getopt' routine that is available on most unix boxes, * */ #include <stdio. h> #include <stdlib. h> #include <string. h> #include <errno. h> #include <fcntl. h> #include <time. h> /* localtime() */ #if defined (_WIN32) #include <io. h> #endif /* Local Headers */ #if defined(_WIN32) StorNext API Guide 136 /* for posix open(2) */ #include <cvinttypes. h> #include <bsd_getopt. c> #include <bsd_strtoll. c> #endif extern char *optarg; extern int optind; #if defined(__linux__) #include <stdint. h> #ifndef NULL #define NULL 0 #endif /* NULL */ #endif /* linux */ #include <extapi. h> #include <cvapi. h> /* for integer typedefs */ /* need a getopt routine */ StorNext API Guide 137 /* Macros */ #if defined(_WIN32) #define ARG64X #define ARG64D #else #define ARG64X #define ARG64D #endif /* _WIN32 */ #define EXTMAX24 #define MAXDISKS 32 "0x%I64x" "%I64d" "0x%llx" "%lld" /* File scope variables */ char *Progname; int Verbose; int ErrorFlag; /* External variables */ extern int optind; /* External functions */ /* Structures and Unions */ /* Signal Catching Functions */ /* NONE */ void Usage() { fprintf(stderr, "Usage: %s <args> filename \n", Progname); fprintf(stderr, "\t -A alloc space\n"); fprintf(stderr, "\t -a affinity\n"); fprintf(stderr, "\t -B stat fs\n"); fprintf(stderr, "\t -b broadcast size on alloc\n"); fprintf(stderr, "\t -C set concurrent write\n"); fprintf(stderr, "\t -c clear concurrent write\n"); fprintf(stderr, "\t -D get disk info for stripe group <n>\n"); fprintf(stderr, "\t -E print extent list\n"); fprintf(stderr, "\t -F set affinity\n"); fprintf(stderr, "\t -f get affinity \n"); fprintf(stderr, "\t -G get stripe group name from Ordinal\n"); fprintf(stderr, "\t -g get stripe group ordinal from Name\n"); fprintf(stderr, "\t -I Info for stripe group <n> \n"); fprintf(stderr, "\t -L get physical Location for offset in file\n"); fprintf(stderr, "\t -l (alloc flag) load extent in client fsd\n"); fprintf(stderr, "\t -N keep size on allocation \n"); fprintf(stderr, "\t -n nbytes [kmg] \n"); fprintf(stderr, "\t -O Open stat file\n"); fprintf(stderr, "\t -o offset [kmg] \n"); fprintf(stderr, "\t -P punch hole \n"); fprintf(stderr, "\t -p get PerfectFit status\n"); fprintf(stderr, "\t -Q (user) set the quota limits for (user)\n"); fprintf(stderr, "\t -q (user) get the quota usage and limits for (user)\n"); fprintf(stderr, "\t -R set read hole fail \n"); fprintf(stderr, "\t -r clear read hole fail \n"); StorNext API Guide 138 fprintf(stderr, fprintf(stderr, fprintf(stderr, fprintf(stderr, fprintf(stderr, fprintf(stderr, fprintf(stderr, fprintf(stderr, fprintf(stderr, fprintf(stderr, fprintf(stderr, fprintf(stderr, } "\t "\t "\t "\t "\t "\t "\t "\t "\t "\t "\t "\t -S -s -T -t -v -V -w -x -Y -y -Z -z stat file (old version)\n"); (alloc flag) stripe align allocation \n"); stat file (new \"plus\" version)\n"); (alloc flag) set perfect fit status\n"); verbose\n"); get version info\n"); wait before exiting\n"); load extents\n"); VerifyAlloc allocation\n"); Toggle PerfectFit status\n"); set file size\n"); size [kmg]\n"); StorNext API Guide 139 /* * PURPOSE * Print out the time for an 'ls' style listing */ void PrintTime( int32_tf_secs) { struct tm*tp; tp = localtime((time_t *)&f_secs); switch (tp->tm_mon) { case 0: printf("Jan"); break; case 1: printf("Feb"); break; case 2: printf("Mar"); break; case 3: printf("Apr"); break; case 4: printf("May"); break; case 5: printf("Jun"); break; case 6: printf("Jul"); break; case 7: printf("Aug"); break; case 8: printf("Sep"); break; case 9: printf("Oct"); break; case 10: printf("Nov"); break; case 11: printf("Dec"); break; } printf(" %d ", tp->tm_mday); printf("%02d:%02d", tp->tm_hour, tp->tm_min); } /* * PURPOSE * Stat file, old version */ int StatFile( int f_fd, StorNext API Guide 140 char { *f_filename) int error = 0; StatReply_t sb; /* * Get the stats */ error = CvApi_CvFstat(f_fd, &sb); if (error) { return error; } /* * Print out the stats in no particular order */ printf("File stats for file '%s'\n", f_filename); printf("Dev %d rdev %d nlink %d bsize %d\n", sb. sr_dev, sb. sr_rdev, sb. sr_nlink, sb. sr_bsize); printf("Size " ARG64D " nblocks " ARG64D "\n", sb. sr_size, sb. sr_nblocks); printf("Inode " ARG64D " uid %d gid %d mode 0%o \n", sb. sr_ino, sb. sr_uid, sb. sr_gid, sb. sr_mode); printf("atime: "); PrintTime(sb. sr_atim); printf(" mtime: "); PrintTime(sb. sr_mtim); printf(" ctime: "); PrintTime(sb. sr_ctim); printf("\n"); return error; } /* * PURPOSE * Stat file, new "plus" version */ int StatFilePlus( int f_fd, char *f_filename) { int error = 0; StatPlusReply_t sb; char *storestate; /* * Get the stats */ error = CvApi_StatPlus(f_fd, &sb); if (error) { return error; } /* * Print out the stats in no particular order */ printf("File stats for file '%s'\n", f_filename); printf("Dev %d nlink %d bsize %d\n", sb. sr_dev, sb. sr_nlink, sb. sr_bsize); switch(sb. sr_storestate) { case STORESTATE_ON_DISK_ONLY: StorNext API Guide 141 storestate = "on disk only"; break; case STORESTATE_ON_TAPE_ONLY: storestate = "on tape only"; break; case STORESTATE_ON_DISK_AND_TAPE: storestate = "on disk and tape"; break; default: storestate = "unknown"; break; } printf("Store state: %d (%s)\n", sb. sr_storestate, storestate); printf("Size " ARG64D " nblocks " ARG64D "\n", sb. sr_size, sb. sr_nblocks); printf("Inode " ARG64D " uid %d gid %d mode 0%o \n", sb. sr_ino, sb. sr_uid, sb. sr_gid, sb. sr_mode); printf("atime: "); PrintTime(sb. sr_atim); printf(" mtime: "); PrintTime(sb. sr_mtim); printf(" ctime: "); PrintTime(sb. sr_ctim); printf("\n"); return error; } StorNext API Guide 142 /* * PURPOSE * Stat VFS */ int StatFs( int f_fd, char *f_filename) { int error = 0; StatFsReply_t sb; time_t esecs; /* * Get the stats */ error = CvApi_StatFs(f_fd, &sb); if (error) { return error; } /* * Print out the stats in no particular order */ printf("FS stats for '%s'\n", f_filename); printf("options: 0x%x\n", sb. fr_options); if (sb. fr_options & FSOPTION_DMIG) printf("\tFSOPTION_DMIG\n"); if (sb. fr_options & FSOPTION_QUOTAS) printf("\tFSOPTION_QUOTAS\n"); if (sb. fr_options & FSOPTION_BRLS) printf("\tFSOPTION_BRLS\n"); if (sb. fr_options & FSOPTION_GLOBALSU) printf("\tFSOPTION_GLOBALSU\n"); if (sb. fr_options & FSOPTION_WINSEC) printf("\tFSOPTION_WINSEC\n"); esecs = (time_t)(sb. fr_epoch / (uint64_t)1000000); printf("epoch: " ARG64X " - %s", sb. fr_epoch, ctime(&esecs)); printf("block size: %d\n", sb. fr_blocksize); printf("total blocks: " ARG64D "\n", sb. fr_total_blocks); printf("blocks free: " ARG64D "\n", sb. fr_blocks_free); printf("inode stripe breadth: " ARG64D "\n", sb. fr_inode_stripe_width); printf("\n"); return error; } /* * PURPOSE * OpenStat file */ int OpenStatFile( int f_fd, char *f_filename) { int error = 0; OpenStatReply_t sb; /* * Get the stats */ error = CvApi_CvOpenStat(f_fd, &sb); StorNext API Guide 143 if (error) { return error; } /* * Print out the stats in no particular order */ printf("File Open_stats for file '%s'\n", f_filename); printf("RefCount: %u\n", sb. os_refcount); printf("OpenCount: %u\n", sb. os_opencount); if(sb. os_sharedread) printf("SharedRead TRUE\n"); else printf("SharedRead FALSE\n"); if(sb. os_sharedwrite) printf("SharedWrite TRUE\n"); else printf("SharedWrite FALSE\n"); printf("\n"); return error; } /* * PURPOSE * Get the physical location for a file given an offset */ int GetPhysLoc( int f_fd, char *f_filename, uint64_t f_offset) { int error = 0; CvExternalExtent_t *exp; PhysLocReply_t loc; /* * Get the location */ error = CvApi_GetPhysLoc(f_fd, f_offset, &loc); if (error) { return error; } printf("Physical location for offset " ARG64X " in file '%s' \n", f_offset, f_filename); exp = &loc. pr_extent; printf("Extent: sg %d file relative base " ARG64X "\n" , exp->ex_sg, exp->ex_frbase); printf(" filesystem base " ARG64X, exp->ex_base); printf(" filesystem end " ARG64X , exp->ex_end); printf("\n"); printf("SG breadth " ARG64X " depth " ARG64X "\n", loc. pr_breadth, loc. pr_depth); printf("volume offset " ARG64X " device relative blkoffset " ARG64X "\n", loc. pr_voloffset, loc. pr_blkoffset); printf("Device pseduo id %x\n", loc. pr_edev); return error; } /* * PURPOSE * Dump out the extents for a file StorNext API Guide 144 */ int GetExtList( intf_fd) { CvExternalExtent_t *buf = NULL, *junkbuf = NULL, *exp; int allocsize; uint32_t cnt, i, numbufs; int error = 0; uint64_t offset; StatReply_t sb; /* * Get the stats */ error = CvApi_CvFstat(f_fd, &sb); if (error) { fprintf(stderr, "Can not stat file, error %d\n", error); return error; } /* * Alloc space for the extent buffer. */ numbufs = EXTMAX; allocsize = sizeof(CvExternalExtent_t) * numbufs; buf = malloc(allocsize); if (buf == NULL) { fprintf(stderr, "Can not alloc space for extent buffers\n"); return 1; } memset(buf, 0, allocsize); if (ErrorFlag == 3) { /* EINVAL */ offset = 99999; } else { offset = 0; } cnt = 0; do { if (ErrorFlag == 2) /* EFAULT */ { error = CvApi_GetExtList(f_fd, offset, &numbufs, junkbuf); } else { error = CvApi_GetExtList(f_fd, offset, &numbufs, buf); } if (error) { if (error != ENOENT) { fprintf(stderr, "Can not get extent list, offset " ARG64X " error %d\n", offset, error); } /* * ENOENT means no more extents */ if ((error == ENOENT) && (ErrorFlag != 1)) { error = 0; StorNext API Guide 145 break; } } exp = buf; for (i=0; i<numbufs; i++) { printf("Extent %d frbase " ARG64X " sg 0x%x fsbase " ARG64X " fsend " ARG64X " depth %x\n", cnt++, exp->ex_frbase, exp->ex_sg, exp->ex_base, exp->ex_end, exp->ex_depth); /* Look for the next extent. */ offset = exp->ex_frbase + ((exp->ex_end + 1) - exp->ex_base); exp++; } } while (error == 0); printf("%d total extents\n", cnt); return error; } /* * PURPOSE * Punch a hole in a file */ int PunchHole( int f_fd, char *f_filename, uint64_t f_offset, uint64_t f_nbytes) { uint64_toffset, end, nblks, freed; int error = 0; offset = f_offset; end = f_offset + f_nbytes; end--; /* last byte, inclusive */ if (Verbose) { printf("Punching a hole in '%s' from " ARG64X " to " ARG64X "\n", f_filename, f_offset, end); } error = CvApi_PunchHole(f_fd, &offset, &end, &nblks, &freed); if (error) { return error; } if (Verbose) { printf("Hole punched in '%s' from " ARG64X " to " ARG64X "blks freed " ARG64X " , blocks now in file " ARG64X "\n", f_filename, offset, end, freed, nblks); } return error; } StorNext API Guide 146 /* * PURPOSE * Load extents space */ int LoadExtents( int f_fd, char *f_filename, uint64_t f_offset, uint64_t f_nbytes) { uint64_toffset, nbytes; int error = 0; offset = f_offset; nbytes = f_nbytes; if (Verbose) { printf("Loading extents in '%s' " ARG64D " bytes at offset " ARG64D "\n", f_filename, nbytes, offset); } error = CvApi_LoadExtents(f_fd, nbytes, offset); if (error) { return error; } if (Verbose) { printf("Loaded " ARG64D " bytes starting at offset " ARG64D "\n", nbytes, offset); } return error; } /* * PURPOSE * Alloc space */ int AllocSpace( int f_fd, char *f_filename, uint64_t f_offset, uint64_t f_nbytes, uint64_t f_affinity, uint32_t f_flags) { uint64_toffset, nbytes; int error = 0; offset = f_offset; nbytes = f_nbytes; if (Verbose) { printf("Allocating space in '%s' " ARG64D " bytes at offset " ARG64D "\n", f_filename, nbytes, offset); } error = CvApi_AllocSpace(f_fd, &nbytes, &offset, f_affinity, f_flags); if (error) { return error; } if (Verbose) { printf("Allocated " ARG64D " bytes starting at offset " ARG64D "\n", nbytes, offset); } StorNext API Guide 147 return error; } /* * PURPOSE * Get PerfectFit status */ int PerfectFitStatus( int f_fd, char *f_filename) { int isperfectfit; int error; error = CvApi_GetPerfectFitStatus(f_fd, &isperfectfit); if (error) { return error; } if (Verbose) { printf("File %s does%s have the PerfectFit bit set. \n", f_filename, isperfectfit ?"" : " not"); } return error; } /* * PURPOSE * Get PerfectFit status */ int TogglePerfectFitStatus( int f_fd, char *f_filename) { int isperfectfit; int setperfectfit; int error; error = CvApi_GetPerfectFitStatus(f_fd, &isperfectfit); if (error) { return error; } if (Verbose) { printf("%s PerfectFit bit on file %s. \n", isperfectfit ? [. . . ]